package com._21cn.cms.article.utils;

import com._21cn.cms.resource.utils.PictureUtil;
import com._21cn.framework.utils.StringUtil;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class FormatContentUtil
{
    private static final Logger log = LoggerFactory.getLogger(FormatContentUtil.class);

    private static Pattern patternP = Pattern.compile("<p[^>]*?>", 2);
    private static Pattern patternDIV = Pattern.compile("<div[^>]*?>", 2);
    private static Pattern patternPage = Pattern.compile("<p[\\s]*class=\"pager\">.*?</p>", 2);
    private static Pattern patternImg = Pattern.compile("<img[^>]*?>", 2);
    private static Pattern patternStrong = Pattern.compile("</?strong[^>]*?>", 2);
    private static Pattern patternScript = Pattern.compile("<[\\s]*?script[^>]*?>[\\s\\S]*?/script[\\s]*?>", 2);
    private static Pattern patternStyle = Pattern.compile("<[\\s]*?style[^>]*?>[\\s\\S]*?/style[\\s]*?>", 2);
    private static Pattern patternStyle2 = Pattern.compile("style=\"[^>]*?[\\s\\S]*?\"", 2);
    private static Pattern patternA = Pattern.compile("</?a[^>]*?>", 2);
    private static Pattern patternEmbed = Pattern.compile("</?embed[^>]*?>", 2);
    private static Pattern patternCenter = Pattern.compile("</?center[^>]*?>", 2);
    private static Pattern patternSpan = Pattern.compile("</?span[^>]*?>", 2);

    public static String replaceP(String content)
    {
        if (StringUtil.isEmpty(content)) {
            return "";
        }
        Matcher matcher = patternP.matcher(content);
        return matcher.replaceAll("<p>");
    }

    public static String replaceDIV(String content)
    {
        if (StringUtil.isEmpty(content)) {
            return "";
        }
        Matcher matcher = patternDIV.matcher(content);
        return matcher.replaceAll("<div>");
    }

    public static String replaceStrong(String content)
    {
        if (StringUtil.isEmpty(content)) {
            return "";
        }
        Matcher matcher = patternStrong.matcher(content);
        return matcher.replaceAll("");
    }

    public static String replaceA(String content)
    {
        if (StringUtil.isEmpty(content)) {
            return "";
        }
        Matcher matcher = patternA.matcher(content);
        return matcher.replaceAll("");
    }

    public static String replaceSpan(String content){
        if(StringUtil.isEmpty(content)){
            return "";
        }
        Matcher matcher = patternSpan.matcher(content);
        return matcher.replaceAll("");
    }

    public static String replaceScript(String content)
    {
        if (StringUtil.isEmpty(content)) {
            return "";
        }
        Matcher matcher = patternScript.matcher(content);
        return matcher.replaceAll("");
    }

    public static String replaceStyle(String content)
    {
        if (StringUtil.isEmpty(content)) {
            return "";
        }
        Matcher matcher = patternStyle.matcher(content);
        return matcher.replaceAll("");
    }

    public static String replaceStyle2(String content)
    {
        if (StringUtil.isEmpty(content)) {
            return "";
        }
        Matcher matcher = patternStyle2.matcher(content);
        return matcher.replaceAll("");
    }

    public static String replaceEmbed(String content)
    {
        if (StringUtil.isEmpty(content)) {
            return "";
        }
        Matcher matcher = patternEmbed.matcher(content);
        return matcher.replaceAll("");
    }

    public static String replaceCenter(String content)
    {
        if (StringUtil.isEmpty(content)) {
            return "";
        }
        Matcher matcher = patternCenter.matcher(content);
        return matcher.replaceAll("");
    }

    public static String replacePage(String content)
    {
        if (StringUtil.isEmpty(content)) {
            return "";
        }
        Matcher matcher = patternPage.matcher(content);
        return matcher.replaceAll("");
    }

    public static String replaceImg(String content)
    {
        return replaceImg(content, "180", true);
    }

    public static String replaceImg(String content, String size, boolean replaceEle) {
        try {
            if (StringUtil.isEmpty(content)) {
                return "";
            }
            Matcher matcherImage = patternImg.matcher(content);
            while (matcherImage.find()) {
                String img = matcherImage.group();
                Matcher matcher = null;
                if (replaceEle) {
                    matcher = Pattern.compile("(width|height|style|type|onload)\\W*=\\W*['\"][^'\"]+?['\"]", 2).matcher(img);
                    while (matcher.find()) {
                        content = content.replace(matcher.group(0), "");
                    }
                }
                matcher = Pattern.compile("src[\\s]*=[\\s]*['\"]([^'\"]+?)['\"]").matcher(img);
                while (matcher.find()) {
                    String imgSrc = matcher.group(1);
                    try {
                        String[] thumbAry = imgSrc.split("/");
                        String imgSize = thumbAry[(thumbAry.length - 2)];
                        String replaceImgSrc = "";
                        if (imgSize.equals("o")) {
                            replaceImgSrc = imgSrc.replaceFirst("/o/", new StringBuilder().append("/m").append(size).append("/").toString());
                        }
                        if (!StringUtil.isEmpty(replaceImgSrc))
                            content = content.replace(imgSrc, replaceImgSrc);
                    }
                    catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return content;
    }

    public static String replaceAllTable(String html)
    {
        String regEx = "<table([\\s\\S]*?)/table>";
        Pattern p = Pattern.compile(regEx, 2);
        Matcher m = p.matcher(html);
        String s = m.replaceAll("");
        return s;
    }

    private static List<String> splitContent(String content, int cutLength)
    {
        List list = new ArrayList();
        int contentLength = content.length();
        int total = (int)Math.floor(contentLength / cutLength) + 2;
        for (int i = 0; i < total; i++) {
            String s = new String(content);
            s = cutContent(s, cutLength);
            list.add(s);
            content = content.replace(s, "");
            if (StringUtil.isEmpty(content))
                break;
        }
        return list;
    }

    private static String cutContent(String content, int cutLength)
    {
        int contentLength = content.length();
        StringBuffer buf = new StringBuffer();
        for (int i = 0; (i < cutLength) &&
                (i < contentLength); i++)
        {
            String s = content.substring(i, i + 1);
            buf.append(s);
            if (Pattern.matches("^[a-zA-Z0-9<>=()（）—、,，。:：《》<>/\\-\\.\"\\ \\'　]+$", s)) {
                cutLength++;
            }
        }

        String result = buf.toString();
        int j = 0;
        if (result.length() >= cutLength) {
            String[] signs = { ",", ".", "?", "!", "，", "。", "？", "！", "<", ">" };
            for (int i = 0; i < signs.length; i++) {
                if (result.lastIndexOf(signs[i]) > j)
                    j = result.lastIndexOf(signs[i]);
            }
            if (j <= 0)
                j = result.length() - 1;
            result = result.substring(0, j + 1);
        }
        return result;
    }

    private static int countChineseWorld(String content)
    {
        int chineseWorld = 0;
        int contentLength = content.length();
        for (int i = 0; i < contentLength; i++) {
            String s = content.substring(i, i + 1);
            if (StringUtil.isOnlyChinese(s)) {
                chineseWorld++;
            }
        }
        return chineseWorld;
    }

    public static List<String> autoSplitContent(String content, int cutLength, int imageWidth, boolean split)
    {
        return autoSplitContent(content, cutLength, imageWidth, split, true);
    }

    public static List<String> autoSplitContent(String content, int cutLength, int imageWidth, boolean split, boolean isSplitA) {
        List resultList = null;

        content = replacePage(content);

        content = replaceP(content);
        if (isSplitA) {
            content = replaceA(content);
            content = replaceEmbed(content);
        }
        content = replaceStrong(content);
        content = replaceScript(content);
        content = replaceStyle(content);

        if (imageWidth > 0) {
            content = replaceImg(content, new StringBuilder().append(imageWidth).append("").toString(), true);
        }

        List list = new ArrayList();
        if (!split) {
            list.add(content);
            resultList = fixSplitContent4P(list);
        } else {
            String[] contentAry = content.split("</p>");
            if (contentAry.length == 1) {
                resultList = splitContent(content, cutLength);
            } else {
                Set<String> set = new LinkedHashSet();
                for (int i = 0; i < contentAry.length; i++) {
                    String blockContent = autoSplitContent4P(content, cutLength);
                    content = content.replace(blockContent, "");
                    set.add(blockContent);
                    if (StringUtil.isEmpty(content)) {
                        break;
                    }
                }
                for (String s : set) {
                    list.add(s);
                }
                resultList = fixSplitContent4P(list);
            }

        }

        resultList = splitByImg(resultList, 3);

        return resultList;
    }

    private static List<String> splitByImg(List<String> list, int maxImgPerPage) {
        List resultList = null;
        if (list == null) {
            return null;
        }

        resultList = new ArrayList(list.size());

        for (int i = 0; i < list.size(); i++) {
            boolean isOverFlow = true;
            int count = 0;
            String pageContent = (String)list.get(i);
            while (isOverFlow) {
                count++;
                if (count > 30) {
                    log.warn(new StringBuilder().append("too many img? loop count:").append(count).append(" content:").append((String)list.get(i)).toString());
                }

                Document doc = Jsoup.parseBodyFragment(pageContent);
                Elements imgs = doc.getElementsByTag("img");

                if (imgs.size() > maxImgPerPage) {
                    Element img = imgs.get(maxImgPerPage);
                    String overFlowImg = img.toString();
                    pageContent = doc.html();
                    int indexOfOverFlow = pageContent.lastIndexOf(overFlowImg);
                    resultList.add(pageContent.substring(0, indexOfOverFlow).replace("<html>", "").replace("</html>", "")
                            .replace("<head>", "")
                            .replace("</head>", "").replace("<body>", "").replace("</body>", ""));
                    pageContent = pageContent.substring(indexOfOverFlow);
                    doc.html(pageContent);
                } else {
                    isOverFlow = false;
                    resultList.add(pageContent.replace("<html>", "").replace("</html>", "")
                            .replace("<head>", "")
                            .replace("</head>", "").replace("<body>", "").replace("</body>", ""));
                }
            }
        }

        return resultList;
    }

    private static String autoSplitContent4P(String content, int maxLength)
    {
        StringBuffer buf = new StringBuffer();
        String[] contentAry = content.split("</p>");
        if (contentAry.length == 1) {
            return content;
        }

        for (int i = 0; i < contentAry.length; i++) {
            if (contentAry[i].indexOf("<p") > -1) {
                buf.append(contentAry[i]).append("</p>");
            }
            if (countChineseWorld(buf.toString()) > maxLength)
                break;
        }
        return buf.toString();
    }

    private static List<String> fixSplitContent4P(List<String> list) {
        List result = new ArrayList();
        for (String s : list) {
            if (!s.startsWith("<p")) {
                s = new StringBuilder().append("<p>").append(s).toString();
            }
            if (!s.endsWith("</p>")) {
                s = new StringBuilder().append(s).append("</p>").toString();
            }
            result.add(s);
        }
        return result;
    }

    public static String filterOutSitePic(String text)
    {
        Document doc = Jsoup.parse(text);
        Elements imgs = doc.select("img");
        for (Element e : imgs) {
            String picUrl = e.attr("src");
            boolean isQiaoliba = PictureUtil.isInPictureLib(picUrl);
            if (!isQiaoliba) {
                e.remove();
            }
        }
        return doc.body().html();
    }

    public static String subString(String text, int length, String endWith) {
        int textLength = text.length();
        int byteLength = 0;
        StringBuffer returnStr = new StringBuffer();
        for (int i = 0; (i < textLength) && (byteLength < length * 2); i++) {
            String str_i = text.substring(i, i + 1);
            if (str_i.getBytes().length == 1)
                byteLength++;
            else {
                byteLength += 2;
            }
            returnStr.append(str_i);
        }
        try {
            if (byteLength < text.getBytes("GBK").length)
                returnStr.append(endWith);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return returnStr.toString();
    }

    public static String trimSpaceStr(String str)
    {
        StringBuilder sb = new StringBuilder(str);
        int index = 0;
        while ((sb.length() > index) &&
                (Character.isWhitespace(sb.charAt(index)))) {
            sb.deleteCharAt(index);
        }

        return sb.toString();
    }

    public static String formatMobileContent(String content, String picSize, int maxLength)
    {
        content = formatContent(content, picSize);
        content = replacePage(content);
        String preContent = autoSplitContent4P(content, maxLength);
        String remainContent = content.replace(preContent, "");
        content = new StringBuilder().append(preContent).append("<div id=\"remainContent\">").append(remainContent).append("</div>").toString();
        return content;
    }

    public static String formatContent(String content, String picSize) {
        content = formatContent(content);
        content = replaceImg(content, picSize, true);
        return content;
    }

    public static String formatContent(String content)
    {
        content = replaceA(content);
        content = replaceStrong(content);
        content = replaceScript(content);
        content = replaceStyle(content);
        content = replaceStyle2(content);
        content = replaceEmbed(content);
        content = replaceAllTable(content);
        content = replaceDIV(content);
        content = replaceSpan(content);
        return content;
    }

    public static void main(String[] args)
            throws Exception
    {
        String content = "<p>\n" +
                "\t&nbsp;</p>\n" +
                "<div>\n" +
                "\t<img class=\"large\" data-loaded=\"0\" data-loadfunc=\"0\" src=\"http://image.qiaoliba.com/photos/album/20190123/o/61B9EB8071ABFD2D221D627CDD2C9716.jpeg\" /></div>\n" +
                "<p>\n" +
                "\t<span class=\"bjh-p\">据新华社圣彼得堡1月22日电（记者鲁金博）俄罗斯国防部22日发布消息说，俄罗斯一架图-22M3远程战略轰炸机在俄摩尔曼斯克降落时坠毁，造成机上3人死亡。</span></p>\n" +
                "<p>\n" +
                "\t<span class=\"bjh-p\">据俄罗斯RT新闻报道，当地时间周二中午，俄罗斯空天军一架图-22M3&ldquo;逆火&rdquo;超音速战略轰炸机在俄罗斯西北部空军基地着陆时遭遇恶劣天气后坠。</span></p>\n" +
                "<p>\n" +
                "\t<span class=\"bjh-p\">据俄罗斯国防部的声明称，这架图-22M3轰炸机在完成例行性飞行训练试图在俄罗斯摩尔曼斯克州奥列涅戈尔斯克市附近的空军基地降落时遭遇暴风雪，随后发生硬着陆事故。轰炸机在硬着陆事故中解体并在事故引发的火灾中被烧毁。</span></p>\n" +
                "<div>\n" +
                "\t<img class=\"large\" data-loaded=\"0\" data-loadfunc=\"0\" src=\"http://image.qiaoliba.com/photos/album/20190123/o/EC7688AFAA5D7A6A1B68A0238F454054.jpeg\" /></div>\n" +
                "<p>\n" +
                "\t<span class=\"bjh-p\">俄罗斯国防部的声明还表示，影响飞机的暴风雪是十分罕见的，一般只发生在北极地区，十分迅速的让原本平静的天气变成了一场猛烈而危险的暴风雪，几乎不可能非常迅速地预测其发展。事发时，这架图-22M3轰炸机上没有携带任何武器。</span></p>\n" +
                "<div>\n" +
                "\t<img class=\"large\" data-loaded=\"0\" data-loadfunc=\"0\" src=\"http://image.qiaoliba.com/photos/album/20190123/o/68A6EBCF8B4E0A5578C94C3A865863E4.jpeg\" /></div>\n" +
                "<p>\n" +
                "\t<span class=\"bjh-p\">据悉，图波列夫图-22M3是一种超音速远程轰炸机，可携带核导弹。该型号轰炸机自20世纪80年代后期开始投入使用。据俄罗斯国际文传电讯社的消息称，根据官方数据，俄罗斯目前拥有100多架图-22M3轰炸机。（编辑：LWC）</span></p>\n" +
                "<p>\n" +
                "\t&nbsp;</p>\n";
        System.out.println(formatContent(content));
    }
}